const axios = require("axios");
const chalk = require("chalk");

/**
 * Gitee API 客户端类
 */
class GiteeClient {
  constructor(accessToken = null) {
    this.baseURL = "https://gitee.com/api/v5";
    this.accessToken = accessToken;
  }

  /**
   * 设置访问令牌
   * @param {string} token - Gitee访问令牌
   */
  setAccessToken(token) {
    this.accessToken = token;
  }

  /**
   * 构建请求URL
   * @param {string} endpoint - API端点
   * @param {object} params - 查询参数
   * @returns {string} 完整的请求URL
   */
  buildURL(endpoint, params = {}) {
    const url = new URL(`${this.baseURL}${endpoint}`);

    // 添加访问令牌
    if (this.accessToken) {
      url.searchParams.append("access_token", this.accessToken);
    }

    // 添加其他参数
    Object.keys(params).forEach((key) => {
      if (params[key] !== undefined && params[key] !== null) {
        url.searchParams.append(key, params[key]);
      }
    });

    return url.toString();
  }

  /**
   * 搜索仓库
   * @param {string} keyword - 搜索关键词
   * @param {object} options - 搜索选项
   * @returns {Promise<Array>} 仓库列表
   */
  async searchRepositories(keyword, options = {}) {
    try {
      const params = {
        q: keyword,
        sort: options.sort || "updated",
        order: options.order || "desc",
        page: options.page || 1,
        per_page: options.perPage || 20,
        language: options.language || null,
        ...options,
      };

      const url = this.buildURL("/search/repositories", params);
      const response = await axios.get(url);

      return response.data;
    } catch (error) {
      console.error(chalk.red("搜索仓库失败:"), error.message);
      throw error;
    }
  }

  /**
   * 获取用户的所有仓库
   * @param {string} username - 用户名
   * @param {object} options - 选项
   * @returns {Promise<Array>} 仓库列表
   */
  async getUserRepositories(username, options = {}) {
    try {
      const params = {
        type: options.type || "all",
        sort: options.sort || "updated",
        direction: options.direction || "desc",
        page: options.page || 1,
        per_page: options.perPage || 20,
        ...options,
      };

      const url = this.buildURL(`/users/${username}/repos`, params);
      const response = await axios.get(url);

      return response.data;
    } catch (error) {
      console.error(chalk.red("获取用户仓库失败:"), error.message);
      throw error;
    }
  }

  /**
   * 获取仓库详细信息
   * @param {string} owner - 仓库所有者
   * @param {string} repo - 仓库名
   * @returns {Promise<Object>} 仓库详细信息
   */
  async getRepository(owner, repo) {
    try {
      const url = this.buildURL(`/repos/${owner}/${repo}`);
      const response = await axios.get(url);

      return response.data;
    } catch (error) {
      console.error(chalk.red("获取仓库信息失败:"), error.message);
      throw error;
    }
  }

  /**
   * 获取仓库的分支列表
   * @param {string} owner - 仓库所有者
   * @param {string} repo - 仓库名
   * @returns {Promise<Array>} 分支列表
   */
  async getBranches(owner, repo) {
    try {
      const url = this.buildURL(`/repos/${owner}/${repo}/branches`);
      const response = await axios.get(url);

      return response.data;
    } catch (error) {
      console.error(chalk.red("获取分支列表失败:"), error.message);
      throw error;
    }
  }

  /**
   * 获取仓库的标签列表
   * @param {string} owner - 仓库所有者
   * @param {string} repo - 仓库名
   * @returns {Promise<Array>} 标签列表
   */
  async getTags(owner, repo) {
    try {
      const url = this.buildURL(`/repos/${owner}/${repo}/tags`);
      const response = await axios.get(url);

      return response.data;
    } catch (error) {
      console.error(chalk.red("获取标签列表失败:"), error.message);
      throw error;
    }
  }

  /**
   * 获取仓库的目录结构
   * @param {string} owner - 仓库所有者
   * @param {string} repo - 仓库名
   * @param {string} path - 路径，默认为根目录
   * @param {string} ref - 分支或标签，默认为main
   * @returns {Promise<Array>} 目录内容
   */
  async getContents(owner, repo, path = "", ref = "main") {
    try {
      const params = { ref };
      const url = this.buildURL(
        `/repos/${owner}/${repo}/contents/${path}`,
        params
      );
      const response = await axios.get(url);

      return response.data;
    } catch (error) {
      console.error(chalk.red("获取目录内容失败:"), error.message);
      throw error;
    }
  }

  /**
   * 获取仓库的README内容
   * @param {string} owner - 仓库所有者
   * @param {string} repo - 仓库名
   * @param {string} ref - 分支或标签，默认为main
   * @returns {Promise<string>} README内容
   */
  async getReadme(owner, repo, ref = "main") {
    try {
      const params = { ref };
      const url = this.buildURL(`/repos/${owner}/${repo}/readme`, params);
      const response = await axios.get(url);

      return response.data.content;
    } catch (error) {
      console.error(chalk.red("获取README失败:"), error.message);
      throw error;
    }
  }
}

module.exports = GiteeClient;
